package cn.jdemo.io.inpustream;

import java.io.*;

/**
 * @see InputStream FilterInputStream的基类
 * @see FilterInputStream BufferedInputStream的基类
 * @see BufferedInputStream (传入io流，缓存读取):
 * (1)实例化需要封装ioStream对象，内部有缓存，默认是8192；
 * (2)支持mark(标记)，并标记readlimit,可以reset重置会mark位置重新读取
 * (3)支持skip.跳过并丢弃此输入流中的n个字节的数据
 *
 * //构造方法
 * @see BufferedInputStream#BufferedInputStream(InputStream in) DEFAULT_BUFFER_SIZE = 8192 = 8*1024
 * @see BufferedInputStream#BufferedInputStream(InputStream in, int size) size为内部缓存大小
 *
 * 同步对象方法
 * @see BufferedInputStream#read()//读取一个字节
 * @see BufferedInputStream#read(byte[] b, int off, int len)//读取多个字节到b
 * @see BufferedInputStream#available() //下一字节是否可读
 * @see BufferedInputStream#mark(int readlimit) //标记, readlimit为mark后最多可读取的字节数;(打标记，重置当前位置到标记的位置重新读取数据)
 * @see BufferedInputStream#reset()//重置回mark位置
 * @see BufferedInputStream#skip(long n)//跳过n个字节
 * 对象方法
 * @see BufferedInputStream#close() 关闭此输入流并释放与该流关联的所有系统资源
 * @see BufferedInputStream#markSupported()//是否支持mark, true
 *
 * @date 2020/12/21
 */
public class Demo01_BufferedInputStream {
    public static void main(String[] args) throws IOException {
        // test01();
        // test02();
        // test03();
        // test04();
        // test05();
        test06();
    }

    public static void test01() throws IOException {
        BufferedInputStream bufferedIS = new BufferedInputStream(new InputStream() {
            @Override
            public int read() throws IOException {
                // return 0;
                return 10;
            }
        });
        int read = bufferedIS.read();
        System.out.println("自定义InputStream输出: "+read);
        bufferedIS.close();
    }

    /**
     * 输出内容:
     * 自定义InputStream输出: 67
     *
     * @see BufferedInputStream#read() 读取一个字节
     * @see BufferedInputStream#close()
     * @throws IOException
     */
    public static void test02() throws IOException {
        InputStream inputStream = new FileInputStream("D:\\1.txt");// 文件io流

        BufferedInputStream bufferedIS = new BufferedInputStream(inputStream);
        int read = bufferedIS.read();
        System.out.println("自定义InputStream输出: "+read);

        bufferedIS.close(); // 方法内部对传入的inputStream，进行了关闭
    }

    /**
     * 问题:
     * (1)每次while循环读取到bytes,会覆盖掉bytes内容，若覆盖不了就会打印多余
     * (2)存在乱码
     * @throws IOException
     */
    public static void test03() throws IOException {
        InputStream inputStream = new FileInputStream("D:\\test.txt");// 文件io流

        BufferedInputStream bufferedIS = new BufferedInputStream(inputStream);
        byte[] bytes = new byte[1024];

        while(bufferedIS.read(bytes) != -1){
            String str = new String(bytes);
            System.out.println(str);
        }
        bufferedIS.close();
    }

    /**
     * @see Demo01#test03() 解决问题(1)
     * @see BufferedInputStream#read(byte[]) 读入缓冲区的字节总数
     * @throws IOException
     */
    public static void test04() throws IOException {
        InputStream inputStream = new FileInputStream("D:\\test.txt");// 文件io流

        BufferedInputStream bufferedIS = new BufferedInputStream(inputStream);
        byte[] bytes = new byte[1024];

        int readBytesNum = 0;
        while( (readBytesNum = bufferedIS.read(bytes)) != -1){
            String str =  new String(bytes,0,readBytesNum);
            System.out.println(str);
        }
        bufferedIS.close();
    }

    /**
     * 每次读取后，前8个字节都是<code>[开始]</code>
     *
     * @see BufferedInputStream#read(byte[], int, int)
     *
     * @throws IOException
     */
    public static void test05() throws IOException {
        byte[] temp = new String("[开始]").getBytes();
        int tempLen = temp.length;// 8
        InputStream inputStream = new FileInputStream("D:\\test.txt");// 文件io流

        BufferedInputStream bufferedIS = new BufferedInputStream(inputStream);
        byte[] bytes = new byte[1024];
        System.arraycopy(temp, 0, bytes, 0, tempLen);

        int readBytesNum = 0;
        while( (readBytesNum = bufferedIS.read(bytes, tempLen,(1024- tempLen))) != -1){
            String str =  new String(bytes,0,readBytesNum);
            System.out.println(str);
        }
        bufferedIS.close();
    }

    /**
     * 标记重置
     *
     * @see BufferedInputStream#mark(int)
     * @see BufferedInputStream#reset()
     * @throws IOException
     */
    public static void test06() throws IOException {
        InputStream inputStream = new FileInputStream("D:\\test.txt");// 文件io流

        BufferedInputStream bufferedIS = new BufferedInputStream(inputStream);
        byte[] bytes = new byte[1024];

        // 读取前先打个标记
        if(bufferedIS.markSupported()){
            bufferedIS.mark(1024);
        }

        // 第一次读取
        int readBytesNum = bufferedIS.read(bytes);
        System.out.println(new String(bytes,0,readBytesNum));

        System.out.println("---------------------------------");
        bufferedIS.reset(); // 重置源码: pos = markpos;

        // 第二次读取
        int readBytesNum02 = bufferedIS.read(bytes);
        System.out.println(new String(bytes,0,readBytesNum02));
        bufferedIS.close();
    }
}
